package xyz.xwls.bootadmin.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.BeansException;

import java.beans.PropertyDescriptor;
import java.util.HashSet;
import java.util.Set;

/**
 * @author WZW
 * @date 2020/4/16
 */
@Slf4j
public class UpdateUtil {

    /**
     * 为目标对象值为{@code null}的属性赋值，防止{@code jpa}执行{@code update}操作时将值设置为null值
     *
     * @param source 源对象
     * @param target 目标对象
     */
    public static void copyNullProperties(Object source, Object target) {
        BeanUtils.copyProperties(source, target, getNotNullProperties(target));
    }

    /**
     * 获取目标对象的非空属性
     *
     * @param target 目标对象
     * @return 非空属性的属性名
     */
    private static String[] getNotNullProperties(Object target) {
        BeanWrapper beanWrapper = new BeanWrapperImpl(target);
        PropertyDescriptor[] propertyDescriptors = beanWrapper.getPropertyDescriptors();
        Set<String> names = new HashSet<>();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            String name = propertyDescriptor.getName();
            try {
                Object value = beanWrapper.getPropertyValue(name);
                if (value != null) {
                    names.add(name);
                }
            } catch (BeansException e) {
                log.error(e.getMessage());
            }
        }
        String[] result = new String[names.size()];
        return names.toArray(result);
    }

}
